﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;

namespace ProductSystem.BLL.Common
{
    public static class StringExtension
    {

        public static string Substring(this string str, int length, string endOf)
        {
            if (!string.IsNullOrEmpty(str) && ((length >= 0) && (length <= str.Length)))
            {
                return (str.Substring(0, length) + endOf);
            }
            return str;
        } 



        #region 类型转换

        /// <summary>
        /// 日期转换
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <param name="defaultValue">转换失败后的缺省值</param>
        /// <returns>转换后日期</returns>
        public static DateTime GetDateTime(this string source, DateTime defaultValue)
        {
            DateTime time;
            if (DateTime.TryParse(source, out time))
            {
                return time;
            }
            return defaultValue;
        }

        /// <summary>
        /// 日期转换，转换失败返回DateTime的最小值
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <returns>转换后日期</returns>
        public static DateTime GetDateTime(this string source)
        {
            return GetDateTime(source, DateTime.MinValue);
        }


        /// <summary>
        /// 日期转换为周
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string GetWeek(DateTime dateTime)
        {
            string weekstr = dateTime.DayOfWeek.ToString();
            switch (weekstr)
            {
                case "Monday": weekstr = "周一"; break;
                case "Tuesday": weekstr = "周二"; break;
                case "Wednesday": weekstr = "周三"; break;
                case "Thursday": weekstr = "周四"; break;
                case "Friday": weekstr = "周五"; break;
                case "Saturday": weekstr = "周六"; break;
                case "Sunday": weekstr = "周日"; break;
                default: weekstr = ""; break;
            }
            return weekstr;
        }

        /// <summary>
        /// 日期转换
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <param name="defaultValue">转换失败后的缺省值</param>
        /// <returns>转换后日期</returns>
        public static bool GetBool(this string source, bool defaultValue = false)
        {
            bool value;
            if (bool.TryParse(source, out value))
            {
                return value;
            }
            return defaultValue;
        }

        /// <summary>
        /// 将字符串转为日期
        /// </summary>
        /// <param name="source">类似（20140730）格式的字符串</param>
        /// <returns></returns>
        public static DateTime FormatDateTime(this string source, string dateFormat)
        {
            try
            {
                DateTime time = DateTime.ParseExact(source, dateFormat, new CultureInfo("zh-CN"), DateTimeStyles.AllowWhiteSpaces);
                return time;
            }
            catch (Exception e)
            {
                return DateTime.MinValue;
            }

        }



        /// <summary>
        /// 转化为整形
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static int GetInt(this string source, int defaultValue)
        {
            int value;
            if (int.TryParse(source, out value))
            {
                return value;
            }
            return defaultValue;
        }

        /// <summary>
        /// 转换为长整形
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static long GetLong(this string source, long defaultValue)
        {
            long value;
            if (long.TryParse(source, out value))
            {
                return value;
            }
            return defaultValue;
        }

        /// <summary>
        /// 转换为浮点型
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static float Getfloat(this string source, float defaultValue)
        {
            float value;
            if (float.TryParse(source, out value))
            {
                return value;
            }
            return defaultValue;
        }

        /// <summary>
        /// 转换为实数
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static double GetDouble(this string source, double defaultValue)
        {
            double value;
            if (double.TryParse(source, out value))
            {
                return value;
            }
            return defaultValue;
        }

        /// <summary>
        /// 转换为实数
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static decimal GetDecemal(this string source, decimal defaultValue)
        {
            decimal value;
            if (decimal.TryParse(source, out value))
            {
                return value;
            }
            return defaultValue;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static decimal? GetNullableDecimal(this string source)
        {
            decimal? result;
            decimal value;
            if (decimal.TryParse(source, out value)) result = decimal.Round(value, 3);
            else result = null;
            return result;
        }

        /// <summary>
        /// 保留三位小数
        /// </summary>
        /// <param name="num">指定的数字</param>
        /// <returns></returns>
        public static string GetThreeDecimal(decimal num)
        {
            return String.Format("{0:N3}", num);
        }

        #endregion

        #region 保留小数位

        /// <summary>
        /// 保留小数位,允许输出为null
        /// </summary>
        /// <param name="item">原始数值</param>
        /// <param name="round">要保留的位数</param>
        /// <returns></returns>
        public static decimal? DecimalRoundOrNull(decimal? item, int round)
        {
            if (item == null)
            {
                return null;
            }
            return (Math.Round(GetDecemal(item.ToString(), 0), round));
        }

        /// <summary>
        /// 保留小数位
        /// </summary>
        /// <param name="item">原始数值</param>
        /// <param name="round">要保留的位数</param>
        /// <param name="defaultValue">默认输出值</param>
        /// <returns></returns>
        public static decimal DecimalRound(decimal? item, int round = 3, decimal defaultValue = 0)
        {
            if (item == null)
            {
                return StringExtension.GetDecemal("0.000", 0);
            }
            return (Math.Round(GetDecemal(item.ToString(), defaultValue), round));

        }


        /// <summary>
        /// 保留小数位
        /// </summary>
        /// <param name="item">原始数值</param>
        /// <param name="round">要保留的位数</param>
        /// <param name="defaultValue">默认输出值</param>
        /// <returns></returns>
        public static string DecimalRound(string item, int round = 3, decimal defaultValue = 0)
        {
            if (!string.IsNullOrEmpty(item))
            {
                return (Math.Round(GetDecemal(item.ToString(), defaultValue), round)).ToString();
            }
            else
            {
                return "--";
            }

        }

        /// <summary>
        /// 保留小数位
        /// </summary>
        /// <param name="item">原始数值</param>
        /// <param name="round">要保留的位数</param>
        /// <param name="defaultValue">默认输出值</param>
        /// <returns></returns>
        public static decimal DecimalRound(decimal item, int round, decimal defaultValue)
        {

            return (Math.Round(GetDecemal(item.ToString(), defaultValue), 3));

        }


        /// <summary>
        /// 保留小数位（如果小数位为0，则取整数）
        /// </summary>
        /// <param name="item">原始数值</param>
        /// <param name="round">要保留的位数</param>
        /// <param name="defaultValue">默认输出值</param>
        /// <returns></returns>
        public static decimal RoundDecimal(decimal? item, int round = 3, decimal defaultValue = 0)
        {
            decimal result = GetDecemal(item.ToString(), defaultValue);


            if (result.ToString().LastIndexOf('.') != -1)      //判断result是否有小数点
            {
                //截取小数点后三位小数，如果全为0，则返回整数
                if (result.ToString().Substring(result.ToString().LastIndexOf('.') + 1, 3) != "000")
                {
                    return (Math.Round(result, round));       //保留round位小数
                }
                else
                {
                    return (Math.Round(result, 0));         //0位小数，即整数
                }
            }
            else
            {
                return result;
            }
        }

        /// <summary>
        /// 乘以10的n次方
        /// </summary>
        /// <param name="item">原始数据</param>
        /// <param name="pow">n次方</param>
        /// <returns></returns>
        public static decimal? DecimalPow(decimal? item, int pow = 3, int round = 0)
        {
            if (item == null)
            {
                return null;
            }
            var result = (decimal)item * (decimal)Math.Pow(10, pow);
            return RoundDecimal(result, round);

        }
        /// <summary>
        /// 乘以10的3次方不保留小数
        /// </summary>
        /// <param name="item">原始数据</param>
        /// <param name="pow">n次方</param>
        /// <returns></returns>
        public static decimal? DecPow(decimal? item, int pow = 3)
        {
            if (item == null)
            {
                return null;
            }
            var result = (decimal)item * (decimal)Math.Pow(10, pow);
            return Math.Round(result, 0);

        }
        /// <summary>
        /// 乘以10的n次方并保留三位小数
        /// </summary>
        /// <param name="item">原始数据</param>
        /// <param name="pow">n次方</param>
        /// <returns></returns>
        public static decimal? DecimalPowNew(decimal? item, int pow)
        {
            if (item == null)
            {
                return null;
            }
            var result = (decimal)item * (decimal)Math.Pow(10, pow);
            return Math.Round(result, 3);

        }

        #endregion
        /// <summary>
        /// 保留一位小数，小数点后第二位小数不是0就进位
        /// </summary>
        /// <param name="item"></param>
        /// <param name="round"></param>
        /// <returns></returns>
        public static decimal RoundDecimalOne(decimal? item, int round = 1)
        {
            decimal result = 0;
            if (item == null)
            {
                result = StringExtension.GetDecemal("0.0", 0);
            }
            else
            {
                if (item.ToString().IndexOf('.') != -1)//有小数点
                {
                    if (Convert.ToInt32(item.ToString().Substring(item.ToString().IndexOf('.') + 2, 1)) > 0)
                    {
                        result = Convert.ToDecimal(item.ToString().Substring(0, item.ToString().IndexOf('.') + 2)) + 0.1M;
                    }
                    else
                    {
                        result = Convert.ToDecimal(item.ToString().Substring(0, item.ToString().IndexOf('.') + 2));
                    }
                }
            }
            return result;

        }
    }
}
